package com.tg.app.activity.device.add;

import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.view.Window;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;

import com.appbase.custom.config.ApiUrl;
import com.appbase.custom.constant.CommonConstants;
import com.base.BaseActivity;
import com.tange.module.add.configure.DeviceApNetworkConfigure;
import com.tange.module.add.match.DeviceMatchQuery;
import com.tange.module.core.wifi.scan.ApScanConfiguration;
import com.tange.module.socket.SocketIoConstants;
import com.tg.app.R;
import com.tg.app.camera.Camera;
import com.tg.app.helper.ActivityHelper;
import com.tg.app.report.DeviceAddReport;
import com.tg.app.report.DeviceAddReportBean;
import com.tg.app.util.LogUtils;
import com.tg.app.view.CustomCircleProgressBar;
import com.tg.appcommon.android.DeviceAddSoundConstants;
import com.tange.base.toolkit.PreferenceUtil;
import com.tg.appcommon.android.SoundPlayerManager;
import com.tange.base.toolkit.StringUtils;
import com.tg.appcommon.android.TGAlertDialog;
import com.tg.appcommon.android.TGApplicationBase;
import com.tg.appcommon.android.TGLog;
import com.tg.data.helper.DeviceTypeHelper;
import com.tg.data.http.entity.DeviceMatchBean;

/**
 * 内含两个流程：
 *  1 发送配网信息给设备
 *  2 向后台轮询配网状态
 */
public  class ApConnectActivity extends BaseActivity {

    private static final String TAG = "ApConnectActivityTAG";

    /** 配网状态轮询*/
    private static final int EVENT_MATCH_POLLING =0;

    /** 配网成功，跳转名称设置页 */
    private static final int EVENT_SET_NAME =1;

    /** 配网失败 s*/
    private static final int EVENT_CONNECT_ERR =2;

    private static final int MAX_POLLING_COUNT = 200;

    private static final int POLLING_DELAY_MS = 1000;

    private String bindToken;

    private boolean isAddSuccess = false;

    private int pollingCount = 0;

    private TextView  progress;
    private CustomCircleProgressBar circleProgressBar;
    private TGAlertDialog  tgAlertDialog;
    private AddDeviceBroadCastReceiver receiver;

    private long deviceID;
    private String mUUID;
    private boolean isError = false;
    private String uuid;

    private String deviceType = "";

    private boolean loginStatusOutOfDate = false;

    private boolean playSound = true;

    private SoundPlayerManager soundPlayerManager;

    private final Handler uiHandler = new Handler(Looper.getMainLooper());

    /** 通用配网协议 */
    private DeviceApNetworkConfigure deviceApNetworkConfigure;

    @SuppressLint("HandlerLeak")
    private final Handler handler = new Handler(){
        @SuppressLint({"HandlerLeak", "DefaultLocale"})
        @Override
        public void handleMessage(Message msg) {
           if (msg.what == EVENT_MATCH_POLLING){
               if (!isAddSuccess){
                   TGLog.i(TAG, "handleMessage [EVENT_MATCH_POLLING] not success, pollingCount = " + pollingCount);
                   if (pollingCount % 5 ==0){
                       matching();
                   }
                   if (pollingCount >= MAX_POLLING_COUNT){
                       connectError();
                       isError = true;
                       return;
                   }

                   pollingCount++;
                   String text = String.format("%d", MAX_POLLING_COUNT - pollingCount);
                   TGLog.i(TAG, "handleMessage [EVENT_MATCH_POLLING] count down = " + text);
                   progress.setText(text);
                   circleProgressBar.setProgress(pollingCount);
                   handler.sendEmptyMessageDelayed(EVENT_MATCH_POLLING, POLLING_DELAY_MS);
                   TGLog.i(TAG, "handleMessage [EVENT_MATCH_POLLING] resent after " + POLLING_DELAY_MS);
               } else {
                   TGLog.i(TAG, "handleMessage [EVENT_MATCH_POLLING] already add.");
               }

           }else if(msg.what  == EVENT_SET_NAME){
               TGLog.i(TAG, "handleMessage [EVENT_SET_NAME]");
               setDeviceName();
           }else if(msg.what  == EVENT_CONNECT_ERR){
               TGLog.i(TAG, "handleMessage [EVENT_CONNECT_ERR]");
               connectError();
               isError = true;
           }
        }
    };

    @Override
    protected void onResume() {
        super.onResume();
        TGLog.i(TAG, "[onResume] isError = " + isError);
        TGLog.i(TAG, "[onResume] isAddSuccess = " + isAddSuccess);

        if (isError){
            connectError();
        }else if (isAddSuccess){
            setDeviceName();
        } else {
            playSound();
        }
    }

    private void playSound() {
        TGLog.i(TAG, "[playSound] playSound = " + playSound);
        if (!playSound) return;
        if (soundPlayerManager != null) {
            soundPlayerManager.destroy();
        }
        soundPlayerManager = SoundPlayerManager.create(this);
        uiHandler.postDelayed(() -> {
            if (soundPlayerManager != null) {
                soundPlayerManager.download(DeviceAddSoundConstants.WifiConnect(ApConnectActivity.this), true);
            }
        }, 1000);
    }


    @Override
    protected void onPause() {
        super.onPause();
        TGLog.i(TAG, "[onPause]");
        pauseSound();
    }

    private void pauseSound() {
        if (!playSound) return;
        uiHandler.removeCallbacksAndMessages(null);
        if (soundPlayerManager != null) {
            soundPlayerManager.destroy();
        }
    }

    @Override
    public boolean shouldSetStatusBarColor() {
        return true;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.fragment_ap_connect);
        hideActionBar();
        initView();

        receiver = new AddDeviceBroadCastReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(SocketIoConstants.NOTIFY_ADD_DEVICE);
        registerReceiver(receiver,filter);

        DeviceAddReportBean bean = DeviceAddReport.getInstance().getReportBean();
        if (bean!=null){
           bean.connectLoadStart = System.currentTimeMillis();
           DeviceAddReport.getInstance().setReportBean(bean);
        }
        LogUtils.trackCustomBeginKVEvent(getBaseContext(),"bind_ap_new","matching");

        deviceType = getIntent().getStringExtra(ApSetWifiActivity.EXT_DEVICE_TYPE);
        if (DeviceTypeHelper.isLockBell(deviceType)) {
            playSound = false;
        }

        String deviceWifi = getIntent().getStringExtra(ApSetWifiActivity.EXT_UUID);
        if (!StringUtils.isEmpty(deviceWifi)){
            mUUID = deviceWifi.replaceAll(ApScanConfiguration.INSTANCE.apNamePrefixEndsWithUnderLine(),"");
        }
        String deviceWifiPwd = getIntent().getStringExtra(ApSetWifiActivity.EXT_HOTSPOT_PWD);
        String deviceWifiCapabilities = getIntent().getStringExtra(ApSetWifiActivity.EXT_HOTSPOT_CAPABILITIES);
        String wifi = getIntent().getStringExtra(ApSetWifiActivity.EXT_WIFI);
        String pwd = getIntent().getStringExtra(ApSetWifiActivity.EXT_PWD);
        boolean isBatteryDevice =  getIntent().getBooleanExtra(ApSetWifiActivity.EXT_BATTERY_DEVICE,false);
        handler.sendEmptyMessageDelayed(EVENT_MATCH_POLLING, POLLING_DELAY_MS);
        int userId = PreferenceUtil.getInt(this, CommonConstants.PRE_USER_ID);

        TGLog.i(TAG, "[onCreate] deviceWifi = " + deviceWifi);
        TGLog.i(TAG, "[onCreate] deviceWifiPwd = " + deviceWifiPwd);
        TGLog.i(TAG, "[onCreate] deviceWifiCapabilities = " + deviceWifiCapabilities);
        TGLog.i(TAG, "[onCreate] deviceType = " + deviceType);
        TGLog.i(TAG, "[onCreate] wifi = " + wifi);
        TGLog.i(TAG, "[onCreate] pwd = " + pwd);
        TGLog.i(TAG, "[onCreate] isBatteryDevice = " + isBatteryDevice);
        TGLog.i(TAG, "[onCreate] userId = " + userId);

        deviceApNetworkConfigure = DeviceApNetworkConfigure.create(
                this, userId, deviceWifi, deviceWifiPwd, wifi, pwd, new DeviceApNetworkConfigure.Callback() {
                    @Override
                    public void onSuccess(String bindToken) {
                        TGLog.i(TAG, "[DeviceApNetworkConfigure][onSuccess] bindToken = " + bindToken);
                        ApConnectActivity.this.bindToken = bindToken;
                    }

                    @Override
                    public void onFailed(int errorCode) {
                        TGLog.i(TAG, "[DeviceApNetworkConfigure][onFailed] errorCode = " + errorCode);
                        handler.removeCallbacksAndMessages(null);
                        handler.sendEmptyMessage(EVENT_CONNECT_ERR);
                    }
                });

        // 为低功耗设备，传一个特殊的P2P ID
        deviceApNetworkConfigure.setIdForP2P(isBatteryDevice ? Camera.CS2_P2pID_LSP : "");
        deviceApNetworkConfigure.send();
    }

    @Override
    protected void initView() {
        circleProgressBar = findViewById(R.id.loading_progress);
        progress = findViewById(R.id.tv_progress);
        findViewById(R.id.back_toolbar).setOnClickListener(view -> btnBackClick());

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        TGLog.i(TAG, "[onDestroy]");
        unregisterReceiver(receiver);
        handler.removeCallbacksAndMessages(null);
        deviceApNetworkConfigure.destroy();
    }

    @Override
    public void onBackPressed() {
        btnBackClick();
    }

    private void matching() {
        TGLog.i(TAG, "[matching] : " + bindToken + ", loginStatusOutOfDate = " + loginStatusOutOfDate);
        if (loginStatusOutOfDate) {
            TGLog.i(TAG,"matching: but login status out-of-date, ignore !");
            return;
        }
        TGLog.i(TAG,"[matching]: isAddSuccess " + isAddSuccess);
        TGLog.i(TAG,"[matching]: bindToken " + bindToken);

        if (!isAddSuccess && !StringUtils.isEmpty(bindToken)) {
            TGLog.i(TAG,"[matching]: sent.");
            DeviceMatchQuery.create().request(bindToken, new DeviceMatchQuery.Callback() {
                @Override
                public void onSuccess(DeviceMatchBean content) {
                    if (loginStatusOutOfDate) {
                        TGLog.i(TAG, "[matching][onSuccess] but login status out-of-date, ignore !");
                        return;
                    }
                    TGLog.i(TAG,"[matching][onSuccess] matching : " + bindToken + ", isAddSuccess = " + isAddSuccess);
                    if (!isAddSuccess){
                        deviceID = content.getId();
                        uuid  = content.getUuid();
                        TGLog.i(TAG, "[matching][onSuccess] deviceID = " + deviceID);
                        TGLog.i(TAG, "[matching][onSuccess] uuid = " + uuid);
                        TGLog.i(TAG, "[matching][onSuccess] online = " + content.getIs_online());

                        handler.removeCallbacksAndMessages(null);
                        handler.sendEmptyMessage(EVENT_SET_NAME);
                        isAddSuccess = true;

                        if (content.getIs_online() == 0){
                            Toast.makeText(getBaseContext(),R.string.device_app_succeed_wait_online,Toast.LENGTH_LONG).show();
                        }
                    }
                }

                @Override
                public void onError(int errorCode, String errorMsg) {
                    TGLog.i(TAG, "[onError] errorCode = " + errorCode);
                    TGLog.i(TAG, "[onError] errorMsg = " + errorMsg);
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        String loginTips = TGApplicationBase.getApplicationContext().getResources().getString(R.string.login_error_tips_need_login);
                        if (errorMsg != null && errorMsg.equals(loginTips)) {
                            loginStatusOutOfDate = true;
                            isError = true;
                            handler.removeCallbacksAndMessages(null);
                            TGLog.i(TAG, "[onError] login error");
                        }
                    }
                }
            });
        }
    }

    private void setDeviceName() {
        TGLog.i(TAG, "[setDeviceName]");
        if (tgAlertDialog !=null){
            tgAlertDialog.cancel();
        }

        setAddEndReport();
        Intent intent = new Intent(getBaseContext(), ApSetNameActivity.class);
        intent.putExtra(ApiUrl.DEVICE_TYPE, deviceType);
        intent.putExtra(ApiUrl.DEVICE_UUID, mUUID);
        intent.putExtra(ApiUrl.DEVICEID,deviceID);
        startActivity(intent);
        finish();
    }

    private void btnBackClick(){
        TGLog.i(TAG, "[btnBackClick]");
        if (tgAlertDialog==null){
            tgAlertDialog = new TGAlertDialog(this).builder().setTitle(R.string.cancel_deivce_add_network).setMessage(R.string.cancle_deivce_add_network_message)
                    .setNegativeButton(getResources().getString(R.string.confirm), v -> {
                        ActivityHelper.gotoAddDeviceHomePage(ApConnectActivity.this);
                        LogUtils.matTrackCustomKVEvent(getBaseContext(),"bind_ap_new","matching_cancel");
                        finish();
                    })
                    .setPositiveButton(R.string.cancle_deivce_add_network_wait, v -> {
                    })
            ;
        }else{
            tgAlertDialog.cancel();
        }
        tgAlertDialog.show();
    }

    private void setAddEndReport(){
        DeviceAddReportBean bean = DeviceAddReport.getInstance().getReportBean();
        if (bean!=null){
            bean.connectLoadEnd = System.currentTimeMillis();
            bean.uuid =  uuid;
            DeviceAddReport.getInstance().setReportBean(bean);
        }
    }
    private void connectError(){

        TGLog.i(TAG, "[connectError]");
        setAddEndReport();
        ActivityHelper.gotoAddFailedActivity(this, null, TextUtils.isEmpty(uuid)?mUUID:uuid, true);
        finish();
    }
    private class AddDeviceBroadCastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            assert action != null;
            TGLog.i(TAG, "[AddDeviceBroadCastReceiver] action = " + action);
            if (action.equals(SocketIoConstants.NOTIFY_ADD_DEVICE)) {
                deviceID  = intent.getLongExtra(CommonConstants.EXT_DEVICE_ID, 0);
                TGLog.i(TAG, "[AddDeviceBroadCastReceiver] deviceID = " + deviceID);
                if (deviceID > 0&& !isError) {
                    if (!isAddSuccess){
                        handler.removeMessages(EVENT_SET_NAME);
                        handler.sendEmptyMessage(EVENT_SET_NAME);
                        isAddSuccess = true;
                    }
                }
            }
        }
    }
}
